package com.fast.fast.common.base.exception;

import com.fast.fast.common.base.constant.enums.ErrorEnum;
import com.fast.fast.common.base.constant.enums.HttpStatusEnum;
import lombok.Data;
import lombok.EqualsAndHashCode;

import java.util.LinkedHashMap;
import java.util.Map;

/**
 * 业务异常类
 *
 * @author lyf
 * @date 2022/01/01 00:00 周六
 **/
@EqualsAndHashCode(callSuper = true)
@Data
public class BizException extends RuntimeException {

    /**
     * 错误码
     */
    private Integer code = 500;

    /**
     * 文件名
     */
    private String fileName;

    /**
     * 方法名
     */
    private String methodName;

    /**
     * 行号
     */
    private String lineNumber;

    /**
     * @param errorEnum 错误枚举
     */
    public BizException(ErrorEnum errorEnum) {
        super(errorEnum.getMsg());
        this.code = errorEnum.getCode();
        set();
    }

    /**
     * @param errorEnum 错误枚举
     * @param msg       自定义消息
     */
    public BizException(ErrorEnum errorEnum, String msg) {
        super(errorEnum.getMsg() + "[" + msg + "]");
        this.code = errorEnum.getCode();
        set();
    }

    /**
     * @param httpStatusEnum http状态枚举
     */
    public BizException(HttpStatusEnum httpStatusEnum) {
        super(httpStatusEnum.getMsg());
        this.code = httpStatusEnum.getCode();
        set();
    }

    /**
     * @param httpStatusEnum http状态枚举
     * @param msg            自定义消息
     */
    public BizException(HttpStatusEnum httpStatusEnum, String msg) {
        super(httpStatusEnum.getMsg() + "[" + msg + "]");
        this.code = httpStatusEnum.getCode();
        set();
    }

    private void set() {
        Map<String, String> map = this.getStackTraceInfo(Thread.currentThread().getStackTrace()[2]);
        this.fileName = map.get("fileName");
        this.methodName = map.get("methodName");
        this.lineNumber = map.get("lineNumber");
    }

    public BizException(String msg) {
        super(msg);
        set();
    }

    public BizException(Throwable cause) {
        super(cause);
        set();
    }

    public BizException(String msg, Throwable cause) {
        super(msg, cause);
        set();
    }

    /**
     * 获取某线程的栈跟踪信息
     *
     * @param stackTraceElement 某线程的栈跟踪元素
     * @return
     */
    public Map<String, String> getStackTraceInfo(StackTraceElement stackTraceElement) {
        String fileName = stackTraceElement.getFileName();
        String methodName = stackTraceElement.getMethodName();
        String lineNumber = String.valueOf(stackTraceElement.getLineNumber());
        Map<String, String> map = new LinkedHashMap<>();
        map.put("fileName", fileName);
        map.put("methodName", methodName);
        map.put("lineNumber", lineNumber);
        return map;
    }
}
